package api

import (
	"crypto/md5"
	"fmt"
	"log"
	"strings"
	"time"
)

import (
	estrings "github.com/guangzhou-meta/go-lib/strings"
)

import (
	"gitee.com/changeden/jd-union-go-sdk/common"
)

func Sign(body *apiBody, appSecret string) (string, error) {
	if body == nil {
		return "", fmt.Errorf("请传入有效的请求体")
	}
	signStr := estrings.NewStringBuilderStr(appSecret)

	err := body.parseParamJson()
	if err != nil {
		return "", err
	}
	checkAndAppend(signStr, body.paramJson, "360buy_param_json")

	accessToken := obstainValue(body.accessToken, func() string {
		return common.DefaultAccessToken
	})
	body.accessToken = &accessToken
	checkAndAppend(signStr, accessToken, "access_token")

	checkAndAppend(signStr, body.appKey, "app_key")

	checkAndAppend(signStr, body.format, "format")

	checkAndAppend(signStr, body.method, "method")

	checkAndAppend(signStr, body.signMethod, "sign_method")

	timestamp := obstainValue(body.timestamp, getTimestamp)
	body.timestamp = &timestamp
	checkAndAppend(signStr, timestamp, "timestamp")

	checkAndAppend(signStr, body.v, "v")

	signStr.Append(appSecret)

	s := signStr.String()
	log.Println("签名前数据: ", s)
	s = strings.ToUpper(fmt.Sprintf("%x", md5.Sum([]byte(s))))
	log.Println("签名: ", s)

	body.sign = s

	return s, nil
}

func checkAndAppend(sb *estrings.StringBuilder, value string, key string) {
	value = strings.TrimSpace(value)
	if value != "" {
		sb.Append(key).Append(value)
	}
}

func obstainValue(value *string, getDef func() string) string {
	if value == nil {
		return getDef()
	}
	v := strings.TrimSpace(*value)
	if len(v) == 0 {
		return getDef()
	}
	return v
}

func getTimestamp() string {
	return time.Now().Format("2006-01-02 15:04:05")
}
